package com.colabox.server;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.logging.Logger;

import com.google.gdata.client.DocumentQuery;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.client.http.GoogleGDataRequest;
import com.google.gdata.client.spreadsheet.SpreadsheetService;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.docs.DocumentListEntry;
import com.google.gdata.data.docs.DocumentListFeed;
import com.google.gdata.data.docs.SpreadsheetEntry;
import com.google.gdata.data.spreadsheet.Column;
import com.google.gdata.data.spreadsheet.Data;
import com.google.gdata.data.spreadsheet.Field;
import com.google.gdata.data.spreadsheet.Header;
import com.google.gdata.data.spreadsheet.ListEntry;
import com.google.gdata.data.spreadsheet.ListFeed;
import com.google.gdata.data.spreadsheet.RecordEntry;
import com.google.gdata.data.spreadsheet.RecordFeed;
import com.google.gdata.data.spreadsheet.SpreadsheetFeed;
import com.google.gdata.data.spreadsheet.TableEntry;
import com.google.gdata.data.spreadsheet.TableFeed;
import com.google.gdata.data.spreadsheet.Worksheet;
import com.google.gdata.data.spreadsheet.WorksheetEntry;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;

public class gdocs {
	private static final Logger log = Logger.getLogger(gdocs.class.getName());

	public DocsService service;
	public SpreadsheetService spreadsheetservice;

	private static final String URL_GROUP_DOCUMENTS = "/documents";
	private static final String URL_PATH = "/private/full";
	public static final String SPREADSHEETS_SERVICE_NAME = "wise";
	public static final String DEFAULT_PROTOCOL = "http";
	public static final String DEFAULT_HOST = "docs.google.com";
	private static final String URL_FEED = "/feeds";
	private static final String URL_CATEGORY_SPREADSHEET = "/-/spreadsheet";

	private com.google.gdata.data.spreadsheet.SpreadsheetEntry sheetEntry = null;
	private TableEntry currTable = null;

	public gdocs(String applicationName) {
		service = new DocsService(applicationName);
		spreadsheetservice = new SpreadsheetService(applicationName);
		//System.setProperty(GoogleGDataRequest.DISABLE_COOKIE_HANDLER_PROPERTY, "true");
	}

	public boolean getAuthToken(String username, String password,
			String token[], String errret) {
		// service.getAuthTokenFactory().
		try {
			token[0] = service.getAuthToken(username, password, null, null,
					"writely", "colabox-notepad");
			// String s =
			// "DQAAAIgAAADYVBZl-1xuBT6xQEsOIbKzdptTHYM99cH3UhKO1uJPRCvQIaWS_ScuWU3oWVFbpAY3zdKCZzTMrXJOYgbZJFfva5kaOdqbqWX0C0NBxod9lT2dnh8jWFPHEN6Aqfqk6a0ZsVK3D6vMDX9cFDq1ev_MF06UcaY7UvonghYubF-ALq44_Qv5FiHWyAcS8cJQwr8";
			service.setUserToken(token[0]);
			// System.out.println("-------pp="+token[0]);
			token[1] = service.getAuthToken("untosil@gmail.com", "ihateself",
					null, null, "wise", "colabox-notepad");
			spreadsheetservice.setUserToken(token[1]);
			return true;
		} catch (Exception e) {
			log.info("login getAuthToken error : " + e.getLocalizedMessage());
			errret = "login getAuthToken error . ";
			return false;
		}

	}

	public boolean setAuthToken(String token1, String token2) {
		// service.getAuthTokenFactory().
		try {
			// String s = service.getAuthToken(username, password,
			// null, null, "writely", "colabox-notepad");
			// String s =
			// "DQAAAIgAAADYVBZl-1xuBT6xQEsOIbKzdptTHYM99cH3UhKO1uJPRCvQIaWS_ScuWU3oWVFbpAY3zdKCZzTMrXJOYgbZJFfva5kaOdqbqWX0C0NBxod9lT2dnh8jWFPHEN6Aqfqk6a0ZsVK3D6vMDX9cFDq1ev_MF06UcaY7UvonghYubF-ALq44_Qv5FiHWyAcS8cJQwr8";
			service.setUserToken(token1);
			// String s2 = service.getAuthToken("untosil@gmail.com",
			// "ihateself",
			// null, null, "wise", "colabox-notepad");
			spreadsheetservice.setUserToken(token2);
			return true;
		} catch (Exception e) {
			log.info("login getAuthToken error : " + e.getLocalizedMessage());
			// errret="login getAuthToken error . ";
			return false;
		}

	}

	public boolean createSpreadsheet(String title) {

		try {
			// getDocsListFeed

			 //URL url = new URL("http://docs.google.com/feeds/default/private/full/");
			//log.info("----createSpreadsheet 1------");
			URL url = buildUrl(URL_GROUP_DOCUMENTS + URL_PATH	+ URL_CATEGORY_SPREADSHEET);
			DocumentListFeed feed = service
					.getFeed(url, DocumentListFeed.class);
			// feed.get
			for (DocumentListEntry entry : feed.getEntries()) {
				// log.info(entry.getTitle().getPlainText());
				if (entry.getTitle().getPlainText().equals("Colabox-Notepad")) {

					return true;
				}
			}
			
			url = buildUrl(URL_GROUP_DOCUMENTS + URL_PATH);
			SpreadsheetEntry entry = new SpreadsheetEntry();
			entry.setTitle(new PlainTextConstruct(title));

			service.insert(url, entry);

			return true;

		} catch (Exception e) {
			log.info("createSpreadsheet error " + e.toString());
			return false;
		}
	}

	public boolean createWorksheetEntry(String wstitle) {
		try {

			URL metafeedUrl = new URL(
					"http://spreadsheets.google.com/feeds/spreadsheets/private/full");
			SpreadsheetFeed feed = spreadsheetservice.getFeed(metafeedUrl,
					SpreadsheetFeed.class);
			for (com.google.gdata.data.spreadsheet.SpreadsheetEntry entry : feed
					.getEntries()) {
				log.info(entry.getTitle().getPlainText());
				if (entry.getTitle().getPlainText().equals("Colabox-Notepad")) {

					sheetEntry = entry;
					//System.out.println("sheetEntry==" + sheetEntry.getKey());
					for (WorksheetEntry workentry : sheetEntry.getWorksheets()) {
						log.info(workentry.getTitle().getPlainText());

						if (workentry.getTitle().getPlainText().equals(wstitle)) {

							return true;
						} else if (workentry.getTitle().getPlainText().equals(
								"Sheet 1")) {

							if (sheetEntry.getWorksheets().size() > 1) {
								workentry.delete();
							}

						}
					}
					break;
				}
			}
			// System.out.println("---6---");
			if (sheetEntry == null) {
				return false;
			}

			// List<WorksheetEntry> worksheets =
			// spreadsheetEntry.getWorksheets();

			WorksheetEntry worksheet = new WorksheetEntry();

			worksheet.setTitle(new PlainTextConstruct(wstitle));
			worksheet.setRowCount(10);
			worksheet.setColCount(6);
			URL worksheetFeedUrl = sheetEntry.getWorksheetFeedUrl();
			// spreadsheetservice.insert(worksheetFeedUrl, worksheet);
			// System.out.println("---9---");
			spreadsheetservice.insert(worksheetFeedUrl, worksheet);
			return true;
		} catch (Exception e) {
			log.info("createWorksheetEntry error " + e.toString());
			return false;
		}
	}

	public boolean createTable(String worksheetname) {
		try {
			URL tableFeedUrl = new URL("http://spreadsheets.google.com/feeds/"
					+ sheetEntry.getKey() + "/tables");

			TableFeed tablefeed = spreadsheetservice.getFeed(tableFeedUrl,
					TableFeed.class);

			boolean isTable = false;
			currTable = null;
			for (TableEntry entry : tablefeed.getEntries()) {
				if (entry.getTitle().getPlainText().equals("notepad")) {
					isTable = true;
					entry.getData().setInsertionMode(Data.InsertionMode.INSERT);
					currTable = entry;
					break;
				}
			}

			if (!isTable) {
				TableEntry tableEntry = new TableEntry();
				tableEntry.setTitle(new PlainTextConstruct("notepad"));
				tableEntry.setWorksheet(new Worksheet(worksheetname));

				tableEntry.setHeader(new Header(1));
				// Specify columns in the table, start row, number of rows.
				Data tableData = new Data();
				tableData.setNumberOfRows(0);
				tableData.setStartIndex(2);
				tableData.setInsertionMode(Data.InsertionMode.INSERT);
				// This table has only one column.
				tableData.addColumn(new Column("A", "ID"));
				tableData.addColumn(new Column("B", "Title"));
				tableData.addColumn(new Column("C", "Content"));
				tableData.addColumn(new Column("D", "Type"));
			    tableData.addColumn(new Column("E", "Begin Time"));
			    tableData.addColumn(new Column("F", "Change Time"));
				tableEntry.setData(tableData);
				currTable = spreadsheetservice.insert(tableFeedUrl, tableEntry);
				log.warning("createTable ok ");
			}
			return true;

		} catch (Exception e) {
			log.info("createTable error " + e.toString());
			return false;
		}

	}

	public boolean addTableField(String id,String title ,String content,String btime,String ctime,String type,String synccounts) {
		try {

			URL recordsFeedUrl = new URL(
					"http://spreadsheets.google.com/feeds/"
							+ sheetEntry.getKey()
							+ "/records/"
							+ currTable.getId().substring(
									currTable.getId().lastIndexOf('/') + 1));

			RecordFeed feed = spreadsheetservice.getFeed(recordsFeedUrl,
					RecordFeed.class);
		
			//log.info("-------------------- syncflag="+syncflag);
			//log.info("-------------------- currtbale="+currTable.getId());
			//log.info("----"+id+"@"+title+"@"+content+"@"+btime+"@"+ctime+"@"+type+"@"+"------");
			
			if (Integer.parseInt(synccounts)==0){
				RecordEntry newEntry = new RecordEntry();
				newEntry.addField(new Field(null, "ID", id));
				if (!title.equals(""))newEntry.addField(new Field(null, "Title", title));
				if (!content.equals(""))newEntry.addField(new Field(null, "Content", content));
				if (!type.equals(""))newEntry.addField(new Field(null, "Type", type));
				if (!btime.equals(""))newEntry.addField(new Field(null, "Begin Time", btime));
				if (!ctime.equals(""))newEntry.addField(new Field(null, "Change Time", ctime));
				spreadsheetservice.insert(recordsFeedUrl, newEntry); 
				
			}else{
				int ContentIdx = 0, TitleIdx = 0, BtimeIdx = 0, IdIdx = 0, TypeIdx = 0, CtimeIdx = 0;
				for (RecordEntry entry : feed.getEntries()) {
	
					int icounter = 0;
					for (Field field : entry.getFields()) {
	
						if (field.getName().equals("ID")) {
							IdIdx = icounter;
						} else if (field.getName().equals("Content")) {
							ContentIdx = icounter;
						} else if (field.getName().equals("Type")) {
							TypeIdx = icounter;
	
						} else if (field.getName().equals("Begin Time")) {
							BtimeIdx = icounter;
	
						} else if (field.getName().equals("Change Time")) {
							CtimeIdx = icounter;
	
						} else if (field.getName().equals("Title")) {
							TitleIdx = icounter;
						}
	
						icounter++;
					}
					break;
	
				}
	
				for (RecordEntry entry : feed.getEntries()) {	
					if (entry.getFields().get(IdIdx).getValue().equals(id)) {
						entry.getFields().get(TitleIdx).setValue(title);
						entry.getFields().get(ContentIdx).setValue(content);
						entry.getFields().get(BtimeIdx).setValue(btime);					
						entry.getFields().get(CtimeIdx).setValue(ctime);
						entry.getFields().get(TypeIdx).setValue(type);
						entry.update();
						break;
					}
	
				}
			}
			return true;
		} catch (Exception e) {
			log.info("add field error " + e.getMessage());
			return false;
		}

	}

	public void createTable2(String worksheetname) {
		try {
			System.out.println("---------listFeedUrl-------");
			/*
			 * URL listFeedUrl = wentry.getListFeedUrl();
			 * System.out.println(listFeedUrl.toString()); ListFeed feed =
			 * spreadsheetservice.getFeed(listFeedUrl, ListFeed.class); for
			 * (ListEntry entry : feed.getEntries()) {
			 * System.out.println(entry.getTitle().getPlainText()); for (String
			 * tag : entry.getCustomElements().getTags()) {
			 * System.out.println("  <gsx:" + tag + ">" +
			 * entry.getCustomElements().getValue(tag) + "</gsx:" + tag + ">");
			 * } }
			 */

			System.out.println("---------A1-------");

			URL tableFeedUrl = new URL("http://spreadsheets.google.com/feeds/"
					+ sheetEntry.getKey() + "/tables");

			System.out.println("---------print tables-------");
			TableFeed tablefeed = spreadsheetservice.getFeed(tableFeedUrl,
					TableFeed.class);

			boolean isTable = false;
			TableEntry currTable = null;
			for (TableEntry entry : tablefeed.getEntries()) {
				if (entry.getTitle().getPlainText().equals("notepad")) {
					isTable = true;
					entry.getData().setInsertionMode(Data.InsertionMode.INSERT);
					currTable = entry;
					break;
				}
			}

			if (!isTable) {
				TableEntry tableEntry = new TableEntry();
				tableEntry.setTitle(new PlainTextConstruct("notepad"));
				tableEntry.setWorksheet(new Worksheet(worksheetname));

				tableEntry.setHeader(new Header(1));
				// Specify columns in the table, start row, number of rows.
				Data tableData = new Data();
				tableData.setNumberOfRows(0);
				tableData.setStartIndex(2);
				tableData.setInsertionMode(Data.InsertionMode.INSERT);
				// This table has only one column.
				tableData.addColumn(new Column("A", "ID"));
				tableData.addColumn(new Column("B", "Content"));
				tableData.addColumn(new Column("C", "Type"));
				tableData.addColumn(new Column("D", "Time"));
				tableEntry.setData(tableData);
				currTable = spreadsheetservice.insert(tableFeedUrl, tableEntry);
				log.warning("createTable ok ");
			}

			URL recordsFeedUrl = new URL(
					"http://spreadsheets.google.com/feeds/"
							+ sheetEntry.getKey()
							+ "/records/"
							+ currTable.getId().substring(
									currTable.getId().lastIndexOf('/') + 1));
			// sheetEntry.getWorksheetFeedUrl()
			// /workEntry.getr
			System.out.println("---------recordsFeedUrl-------"
					+ recordsFeedUrl.toString());
			/*
			 * for (int i=0;i<=100;i++){ 
			 * RecordEntry newEntry = new RecordEntry();
			 * 
			 * newEntry.addField(new Field(null, "ID", i+""));
			 * newEntry.addField(new Field(null, "Content", i+"content"));
			 * newEntry.addField(new Field(null, "Type", i+"type"));
			 * newEntry.addField(new Field(null, "Time", i+"time"));
			 * spreadsheetservice.insert(recordsFeedUrl, newEntry); }
			 */

			RecordFeed feed = spreadsheetservice.getFeed(recordsFeedUrl,
					RecordFeed.class);
			int ContentIdx = 0, IdIdx = 0, TypeIdx = 0, TimeIdx = 0;
			for (RecordEntry entry : feed.getEntries()) {

				int icounter = 0;
				for (Field field : entry.getFields()) {

					if (field.getName().equals("ID")) {
						IdIdx = icounter;
					} else if (field.getName().equals("Content")) {
						ContentIdx = icounter;
					} else if (field.getName().equals("Type")) {
						TypeIdx = icounter;

					} else if (field.getName().equals("Time")) {
						TimeIdx = icounter;
					}

					icounter++;
				}
				break;

			}

			for (RecordEntry entry : feed.getEntries()) {

				if (entry.getFields().get(IdIdx).getValue().equals("1")) {
					entry.getFields().get(ContentIdx).setValue("new content");
					entry.getFields().get(TypeIdx).setValue("new type");
					entry.getFields().get(TimeIdx).setValue("new time");
					entry.update();
					break;
				}

			}

		} catch (Exception e) {
			log.info("createTable error " + e.getMessage());
		}

	}

	/**
	 * 
	 * @param path
	 *            the path to add to the protocol/host
	 * 
	 * @throws MalformedURLException
	 * @throws DocumentListException
	 */
	private URL buildUrl(String path) {

		return buildUrl(path, null);
	}

	/**
	 * Builds a URL with parameters.
	 * 
	 * @param path
	 *            the path to add to the protocol/host
	 * @param parameters
	 *            parameters to be added to the URL.
	 * 
	 * @throws MalformedURLException
	 * @throws DocumentListException
	 */
	private URL buildUrl(String path, String[] parameters) {

		return buildUrl(DEFAULT_HOST, path, parameters);
	}

	/**
	 * Builds a URL with parameters.
	 * 
	 * @param host
	 *            the domain of the server
	 * @param path
	 *            the path to add to the protocol/host
	 * @param parameters
	 *            parameters to be added to the URL.
	 * 
	 * @throws MalformedURLException
	 * @throws DocumentListException
	 */
	private URL buildUrl(String host, String path, String[] parameters) {
		try {
			StringBuffer url = new StringBuffer();
			url.append(DEFAULT_PROTOCOL + "://" + host + URL_FEED + path);

			if (parameters != null && parameters.length > 0) {
				url.append("?");
				for (int i = 0; i < parameters.length; i++) {
					url.append(parameters[i]);
					if (i != (parameters.length - 1)) {
						url.append("&");
					}
				}
			}

			return new URL(url.toString());
		} catch (Exception e) {
			log.info("build url error " + e.getMessage());
			return null;
		}
	}

}